#include <memory>

#include "localcommon.hpp"
#include "localreactor.hpp"
#include "locallistener.hpp"
#include "localchannel.hpp"
#include "netcal.hpp"

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        SerErr();
        exit(ERR_SER);
    }
    uint16_t tcp_port = std::stoi(argv[1]);

    // 建立守护进程
    //::daemon(0, 0);

    // 1.构建业务模块
    std::shared_ptr<NetCal> ma_cal = std::make_shared<NetCal>();

    // 2.构建协议对象->通过回调将Request发送，获得NetCal的Response返回
    std::shared_ptr<Protocol> ma_pro = std::make_shared<Protocol>(
        [&ma_cal](Request &req) -> Response
        { return ma_cal->NetCalculation(req); });

    // 3.构建Listen套接字->用于获取后续链接
    std::shared_ptr<Local_Connection::LocalConnection> listenconn = std::make_shared<Local_Connection::LocalListener>(tcp_port);

    // 4.添加回掉函数
    listenconn->RegisterHandler(
        [&ma_pro](std::string &request_str) -> std::string
        {
            std::cout << "脱离网络，进入:协议模块... " << std::endl;
            std::cout << "获得网络报文: {\n"
                      << request_str << "}网络报文结束。" << std::endl;
            std::string response_str;
            while (true)
            {
                std::string package;
                if (!ma_pro->Decode(request_str, &package))
                    break;
                std::cout << "网络报文Decode: {\n"
                          << package << "}Decode结束。" << std::endl;

                response_str += ma_pro->GetRequest(package);
            }
            std::cout << "网络应答GetRequest: {\n"
                      << response_str << "}GetRequest结束。" << std::endl;

            std::cout << "脱离协议模块，进入:网络... " << std::endl;
            return response_str;
        });

    // 5.创建Reactor反应堆，管理所有文件描述符
    std::unique_ptr<Local_Reactor::Reactor> ma_server = std::make_unique<Local_Reactor::Reactor>();
    ma_server->AddConnection(listenconn);
    ma_server->Start();

    return 0;
}
